using B.S.Data.MES.API.Dto.InvoiceDTO;
using B.S.Domain.InvoiceManagement;
using B.S.Domain.基础数据.客户管理;
using B.S.Infratrctrue;
using B.S.Requst;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Data.MES.API.Applications.B.S.KApplications.Query.InvoiceQuery
{
    /// <summary>
    /// 获取所有销售发票列表查询处理程序
    /// 处理无查询条件的销售发票列表请求
    /// </summary>
    public class GetAllSalesInvoiceQueryHandler : IRequestHandler<GetAllSalesInvoiceQuery, APIRequst<List<SalesInvoiceDTO>>>
    {
        private readonly IBaseRepository<SalesInvoice> _salesInvoiceRepository;
        private readonly IBaseRepository<client> _customerRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="salesInvoiceRepository">销售发票仓储</param>
        /// <param name="customerRepository">客户仓储</param>
        public GetAllSalesInvoiceQueryHandler(IBaseRepository<SalesInvoice> salesInvoiceRepository, 
                                             IBaseRepository<client> customerRepository)
        {
            _salesInvoiceRepository = salesInvoiceRepository;
            _customerRepository = customerRepository;
        }

        /// <summary>
        /// 处理获取所有销售发票列表的请求
        /// </summary>
        /// <param name="request">查询请求对象</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>包含所有销售发票列表的API响应</returns>
        public async Task<APIRequst<List<SalesInvoiceDTO>>> Handle(GetAllSalesInvoiceQuery request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询所有未删除的销售发票
                var salesInvoices = await _salesInvoiceRepository.GetAll()
                                                                .Where(s => !s.isDel)
                                                                .OrderByDescending(s => s.InvoiceId)
                                                                .ToListAsync(cancellationToken);

                // 获取相关的客户信息
                var customerIds = salesInvoices.Select(s => s.CustomerId).Distinct().ToList();
                var customers = await _customerRepository.GetListAsync(c => customerIds.Contains(c.CustomerID), cancellationToken);
                var customerDict = customers.ToDictionary(c => c.CustomerID, c => c);

                // 转换为DTO列表
                var salesInvoiceDTOs = new List<SalesInvoiceDTO>();
                foreach (var invoice in salesInvoices)
                {
                    var dto = new SalesInvoiceDTO
                    {
                        InvoiceId = invoice.InvoiceId,
                        InvoiceNo = invoice.InvoiceNo,
                        CustomerId = invoice.CustomerId,
                        CustomerName = invoice.Customer != null ? invoice.Customer.Customername : string.Empty,
                        InvoiceDate = invoice.InvoiceDate,
                        InvoiceStatus = invoice.InvoiceStatus,
                        InvoiceStatusName = GetInvoiceStatusName(invoice.InvoiceStatus),
                        InvoiceAmount = invoice.InvoiceAmount,
                        CreateTime = invoice.CreateTime,
                        CreateName = invoice.CreateName,
                        UpdateTime = invoice.UpdateTime,
                        UpdateName = invoice.UpdateName,
                        Remarks = invoice.Remarks,
                        OrderId = invoice.OrderId,
                        InvoiceType = invoice.InvoiceType,
                        TaxRate = invoice.TaxRate,
                        TaxAmount = invoice.TaxAmount,
                        SubtotalAmount = invoice.SubtotalAmount
                    };

                    // 获取客户名称（如果数据库中没有存储客户名称）
                    if (string.IsNullOrEmpty(dto.CustomerName) && customerDict.TryGetValue(dto.CustomerId, out var customer))
                    {
                        dto.CustomerName = customer.Customername;
                    }

                    salesInvoiceDTOs.Add(dto);
                }

                // 返回成功结果
                return new APIRequst<List<SalesInvoiceDTO>>
                {
                    Code = RequstCode.成功,
                    Data = salesInvoiceDTOs,
                    Msg = "获取所有销售发票成功"
                };
            }
            catch (Exception ex)
            {
                // 记录异常并返回失败结果
                return new APIRequst<List<SalesInvoiceDTO>>
                {
                    Code = RequstCode.失败,
                    Msg = $"获取销售发票失败：{ex.Message}"
                };
            }
        }

        /// <summary>
        /// 根据发票状态代码获取状态名称
        /// </summary>
        /// <param name="statusCode">状态代码</param>
        /// <returns>状态名称</returns>
        private string GetInvoiceStatusName(int statusCode)
        {
            switch (statusCode)
            {
                case 0:
                    return "待开具";
                case 1:
                    return "已开具";
                case 2:
                    return "已作废";
                case 3:
                    return "已红冲";
                default:
                    return "未知状态";
            }
        }
    }
}